<template>
    <div class="square">
      <div class="square-header">
        <div class="title">合同上传 比对差异</div>
        <div>精准比对文档增删改查，高亮定位差异信息</div>
      </div>
      <div class="square-body">
        <!-- 左侧上传区域 -->
        <div class="upload-container">
          <el-upload class="upload-demo" drag :before-upload="handleBeforeUploadLeft" :show-upload-list="false"     :limit="1"
       action="" multiple>
            <div class="uplod-title">主板</div>
            <img src="@/assets/images/file.png" width="60px" height="60px" />
            <div class="el-upload__text">
              点击或将文件拖拽到这里上传
            </div>
          </el-upload>
          <div v-if="fileLeftName" class="uploaded-file-info">
            <span>{{ fileLeftName }}</span>
            <el-button type="text" @click="removeFile('left')">删除</el-button>
          </div>
        </div>
  
        <!-- 右侧上传区域 -->
        <div class="upload-container">
          <el-upload class="upload-demo"  :limit="1" drag :before-upload="handleBeforeUploadRight" :show-upload-list="false" action="" multiple>
            <div class="uplod-title">副板</div>
            <img src="@/assets/images/file.png"  width="60px" height="60px" />
            <div class="el-upload__text">
              点击或将文件拖拽到这里上传
            </div>
          </el-upload>
          <div v-if="fileRightName" class="uploaded-file-info">
            <span>{{ fileRightName }}</span>
            <el-button type="text" @click="removeFile('right')">删除</el-button>
          </div>
        </div>
      </div>
      <div class="square-footer">
        <el-button type="primary" @click="startComparison" :disabled="!fileLeft || !fileRight">开始合同比对</el-button>
      </div>
      <el-dialog v-model="dialogVisible" width="1200px">
        <div>合同对比</div>
        <div class="comparison-view">
          <div class="document-comparison">
            <div class="document-left">
              <div v-html="documentContentLeft"></div>
            </div>
            <div class="document-right">
              <div v-html="documentContentRight"></div>
            </div>
            <div class="difference-report">
              <h3>{{isContent?'总结':'差异报告'}}</h3>
              <div v-if="!isContent" v-html="differenceReport"></div>
              <div  v-loading="loading" v-else v-html="markdown.render(differenceReport)"></div>
            </div>
          </div>
        </div>
        
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="dialogVisible = false">取消</el-button>
            <el-button type="primary" @click="recompare">重新比对</el-button>
            <el-button type="primary" @click="handEnd">{{ isContent ? '报告差异' : '总结' }}</el-button>
          </span>
        </template>
      </el-dialog>
    </div>
  </template>
  
  <script setup lang="ts">
  import { ref, ComponentInternalInstance, getCurrentInstance } from 'vue';
  import mammoth from 'mammoth';
  import * as DiffMatchPatch from 'diff-match-patch';
  import { ElMessage } from 'element-plus';
  import MarkdownIt from 'markdown-it';
  
  const markdown = new MarkdownIt();
  const { proxy } = getCurrentInstance() as ComponentInternalInstance;
  
  // 定义响应式数据
  const documentContentLeft = ref('');
  const documentContentRight = ref('');
  const fileLeft = ref<File | null>(null);
  const fileRight = ref<File | null>(null);
  const dialogVisible = ref(false);
  const differenceReport = ref('');
  const fileLeftName = ref('');
  const fileRightName = ref('');
  const isContent = ref(false);
  const aiContent = ref('');
  const loading = ref(false); // 加载状态
  const maxRetries = 10; // 最大重试次数
  const retryInterval = 3000; // 每次重试间隔时间（毫秒）
  
  /**
   * 提取HTML中的纯文本
   * @param {String} html - HTML字符串
   */
  const extractTextFromHtml = (html: string) => {
    const tempDiv = document.createElement('div');
    tempDiv.innerHTML = html;
    return tempDiv.textContent || tempDiv.innerText || '';
  };
  
  /**
   * 处理左侧文件上传前的操作
   * @param {File} file - 上传的文件对象
   */
  const handleBeforeUploadLeft = (file: File) => {
    fileLeft.value = file;
    fileLeftName.value = file.name;
    convertDocxToHtml(file, 'left');
  
    return false; // 阻止自动上传
  };
  
  /**
   * 处理右侧文件上传前的操作
   * @param {File} file - 上传的文件对象
   */
  const handleBeforeUploadRight = (file: File) => {
    fileRight.value = file;
    fileRightName.value = file.name;
    convertDocxToHtml(file, 'right');
  
    return false; // 阻止自动上传
  };
  
  /**
   * 删除文件
   * @param {String} side - 左侧还是右侧 ('left' 或 'right')
   */
  const removeFile = (side: 'left' | 'right') => {
    if (side === 'left') {
      fileLeft.value = null;
      fileLeftName.value = '';
    } else if (side === 'right') {
      fileRight.value = null;
      fileRightName.value = '';
    }
  };
  
  /**
   * 将.docx文件转换为HTML并显示
   * @param {File} file - .docx文件对象
   * @param {String} side - 左侧还是右侧 ('left' 或 'right')
   */
  const convertDocxToHtml = (file: File, side: 'left' | 'right') => {
    const reader = new FileReader();
    reader.onload = (e) => {
      const arrayBuffer = e.target?.result;
      if (arrayBuffer) {
        mammoth.convertToHtml({ arrayBuffer })
          .then((result) => {
            if (side === 'left') {
              documentContentLeft.value = result.value;
            } else if (side === 'right') {
              documentContentRight.value = result.value;
            }
          })
          .catch((error) => {
            console.error('Error during conversion: ', error);
          });
      }
    };
    reader.readAsArrayBuffer(file); // 以ArrayBuffer格式读取文件
  };
  
  /**
   * 开始合同比对
   */
  const startComparison = () => {
    if (fileLeft.value && fileRight.value) {
      generateDifferenceReport();
      dialogVisible.value = true;
    }
  };
  
  /**
   * 生成差异报告
   */
  let report = ref('');
  const generateDifferenceReport = async () => {
    const dmp = new DiffMatchPatch.diff_match_patch();
  
    // 提取纯文本
    const textLeft = extractTextFromHtml(documentContentLeft.value);
    const textRight = extractTextFromHtml(documentContentRight.value);
  
    const diffs = dmp.diff_main(textLeft, textRight);
    dmp.diff_cleanupSemantic(diffs);
  
    let leftHighlighted = '';
    let rightHighlighted = '';
  
    const diffData = ref({
      add: [],
      del: []
    });
  
    diffs.forEach(([op, text]) => {
      if (op === 1) { // 插入
        differenceReport.value += `<span style="color:green">${escapeHtml(text)}</span>`;
        diffData.value.add.push(text);
      } else if (op === -1) { // 删除
        diffData.value.del.push(text);
        differenceReport.value += `<span style="color:red">${escapeHtml(text)}</span>`;
      } else { // 相同
        differenceReport.value += escapeHtml(text);
      }
    });
    report.value = differenceReport.value;
    documentContentLeft.value = leftHighlighted || documentContentLeft.value;
    documentContentRight.value = rightHighlighted || documentContentRight.value;
    await sendMessage(differenceReport.value);
  };
  
  const sendMessage = async (sendText: string) => {
    await proxy?.$api.post("https://api.coze.cn/v3/chat?conversation_id=7474103125985771574", {
      bot_id: "7473881775774269478",
      user_id: "1234",
      stream: false,
      auto_save_history: true,
      additional_messages: [
        {
          role: "user",
          content: '总结这个合同' + sendText,
          content_type: "text"
        }
      ]
    }, {
      headers: {
        Authorization: 'Bearer pat_HnexrWOR1z6haUl7hh3xqV316TxWQN4KWeHj9RxAAbjGFepfxo2edROAS9v5GcuS',
        "Content-Type": "application/json",
      },
    });
  };
  
  const getMessagesWithRetry = async (retryCount = 0): Promise<string | null> => {
    loading.value = true;
    try {
      const res = await proxy?.$api.get("https://api.coze.cn/v1/conversation/message/list?conversation_id=7474103125985771574", {
        order: "ASC"
      }, {
        headers: {
          Authorization: 'Bearer pat_HnexrWOR1z6haUl7hh3xqV316TxWQN4KWeHj9RxAAbjGFepfxo2edROAS9v5GcuS',
          "Content-Type": "application/json",
        },
      });
  
      if (res.data.length > 0 && res.data[0].role === 'assistant') {
        loading.value = false;
        return res.data[0].content;
      } else if (retryCount < maxRetries) {
        setTimeout(() => {
          getMessagesWithRetry(retryCount + 1);
        }, retryInterval);
      } else {
        loading.value = false;
  
        return null;
      }
    } catch (error) {
      loading.value = false;
  
      return null;
    }
  };
  
  const index = ref(0);
  const handEnd = async () => {
    isContent.value = !isContent.value;
  
    if (index.value === 0) {
      aiContent.value = await getMessagesWithRetry();
    }
  
    if (isContent.value) {
      differenceReport.value = aiContent.value || '';
    } else {
      differenceReport.value = report.value;
    }
  
    index.value++;
  };
  
  /**
   * 转义HTML特殊字符
   * @param {String} str - 原始字符串
   */
  const escapeHtml = (str: string) => {
    return str.replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;')
      .replace(/'/g, '&#039;');
  };
  
  /**
   * 重新比对
   */
  const recompare = () => {
    dialogVisible.value = false;
    fileLeft.value = null;
    fileRight.value = null;
    fileLeftName.value = '';
    fileRightName.value = '';
    documentContentLeft.value = '';
    documentContentRight.value = '';
    differenceReport.value = '';
  };
  </script>
  
  <style lang="scss" scoped>
  .square-header {
    display: flex;
    justify-content: center;
    flex-direction: column;
    font-size: 16px;
    margin-top: 50px;
    margin-bottom: 50px;
    text-align: center;
  }
  
  .dialog-footer {
    display: flex;
    justify-content: center;
    text-align: center;
  }
  
  .title {
    margin: 10px 0;
    font-weight: 700;
  }
  
  .square-body {
    display: flex;
    justify-content: space-between;
    width: 1040px;
    margin: 20px auto;
  }
  
  .upload-container {
    width: 1000px;
  
  }
  :deep(.el-upload-dragger){
    width: 500px;
    height: 300px;
    background-color: #fafafa;
  }
  
  .uploaded-file-info {
    margin-top: 10px;
    font-size: 14px;
    color: #606266;
  }
  
  .square-footer {
    display: flex;
    margin-top: 10px;
    justify-content: center;
  }
  
  .upload-demo {
    width: 500px;
    display: flex;
    justify-content: center;
    align-items: center;
    text-align: center;
    flex-direction: column;
  }
  .upload-demo img{
    position: relative;
    top: -100px;
  }
  
  .el-upload__text{
    position: relative;
    top: -100px;
  }
  .document-text {
    font-size: 12px;
  }
  
  .comparison-view {
    display: flex;
    height: 60vh;
  }
  
  .document-comparison {
    display: flex;
    width: 100%;
    height: 100%;
    flex-direction: row;
  }
  .uplod-title{
    font-size: 24px;
    font-weight: 700;
  }
  .difference-report,
  .document-left,
  .document-right {
    width: 400px;
    height: 100%;
    overflow-y: auto;
    padding: 10px;
    border: 1px solid #ccc;
  }
  
  .document-left {
    border-right: none;
  }
  
  .document-right {
    border-left: none;
  }
  
  :deep(.el-dialog__header) {
    margin: 10px;
    padding: 10px;
    height: 0px;
  }
  </style>